﻿using System;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;

[Serializable]
public class ToggleChild {
    public Image image;
    public Sprite highlightedSprite;
    public Sprite disabledSprite;
}

[Serializable]
public class ToggleObjActive
{
    public GameObject highlightedGo;
    public GameObject disabledGo;
}

[RequireComponent(typeof(RectTransform))]
public class ToggleEx : Toggle {
    private Action<int, string> callBack;
    private Action<int, string> disAbleCallBack;
    private Action<bool> statusCallback;
    public Action<PointerEventData, Toggle> onClickCallback;

    private Animator animator;

    private Toggle toggle;
    public Toggle _Toggle {
        get {
            if ( toggle == null )
                toggle = gameObject.GetComponent<Toggle>();
            return toggle;
        }
    }
    
    public string highlightedAnim;
    public string normalAnim;
    public float highlightedScale = 1;
    public ToggleChild[] children;
    public ToggleObjActive[] childrenObj;

    private int _index = 0;
    
    public void Awake()
    {
        toggle = gameObject.GetComponent<Toggle>();
        toggle.onValueChanged.AddListener( OnTabChanged );
        OnTabChanged(toggle.isOn);
    }

    public void Init(int index, Action<int, string> handler, Action<int, string> disableHandler = null)
    {
        _index = index;
        animator = GetComponent<Animator>();
        callBack = handler;
        disAbleCallBack = disableHandler;
    }

    public void OnStatusChanged( Action<bool> status) 
    {
        statusCallback = status;
    }
    
    void OnTabChanged( bool b ) 
    {
        statusCallback?.Invoke(b);

        if (Math.Abs(highlightedScale - 1) > float.Epsilon)
        {
            transform.localScale = Vector3.one * (b ? highlightedScale : 1);
        }

        UpdateAnimState(b);

        for ( int i = 0; i < children.Length; i++ ) {
            if ( !children[i].image )
                continue;
            children[i].image.sprite = b ? children[i].highlightedSprite : children[i].disabledSprite;
        } 

        for (int i = 0; i < childrenObj.Length; i++)
        {
            if (childrenObj[i].disabledGo != null)
            {
                childrenObj[i].disabledGo.SetActive(!b);
            }
            if ( childrenObj[i].highlightedGo != null)
            {
                childrenObj[i].highlightedGo.SetActive(b);
            }
        }

        if ( !b )
        {
            if(null != disAbleCallBack)
            {
                disAbleCallBack(_index, name);
            }
            return;
        }
        if ( callBack != null )
            callBack(_index, name);
    }

    public void UpdateAnimState(bool b)
    {
        if (animator)
        {
            if (b)
            {
                if (!string.IsNullOrEmpty(highlightedAnim))
                {
                    animator.SetBool(highlightedAnim, true);
                }
            }
            else
            {
                if (!string.IsNullOrEmpty(normalAnim))
                {
                    animator.SetBool(normalAnim, true);
                }
            }
        }
    }

    public override void OnPointerClick(PointerEventData eventData)
    {
        base.OnPointerClick(eventData);
        if (onClickCallback != null)
            onClickCallback.Invoke(eventData, toggle);
    }
}
